#include "mysqlDataBase.h"
#include <iostream>

// 构造
MySqlDataBase::MySqlDataBase(const std::string &host, const std::string &user, const std::string &passwd)
{
    m_db = mysql_init(nullptr);
    if (m_db == NULL)
    {
        throw std::runtime_error("init failed");
    }
    m_host = host.c_str();
    m_user = user.c_str();
    m_passwd = passwd.c_str();
}

// 析构
MySqlDataBase::~MySqlDataBase()
{
    if (m_db != nullptr)
    {
       close();
    }
}

// 连接数据库
bool MySqlDataBase::connectDB(const std::string &connStr)
{
    // 连接mysql服务器
    if (mysql_real_connect(m_db, m_host.c_str(), m_user.c_str(), m_passwd.c_str(), connStr.c_str(), 3306, NULL, 0) == NULL)
    {
        std::cout << "mysql connect error" << std::endl;
        return false;
    }
    return true;
}

// 执行Sql执行语句(exec)
bool MySqlDataBase::executeSql(const std::string &sql)
{
    if (mysql_query(m_db, sql.c_str()))
    {
        std::cout << "file:" << __FILE__ << ", line:" << __LINE__ << mysql_error(m_db) << std::endl;
        return false;
    }
    return true;
}

// 执行Sql查询语句(select)
QueryResult MySqlDataBase::querySql(const std::string &sql)
{
    QueryResult result;

    if (mysql_query(m_db, sql.c_str()))
    {
        std::cout << "file:" << __FILE__ << ", line:" << __LINE__ << mysql_error(m_db) << std::endl;
        return result;
    }

    // 从结果集里面拿取数据
    MYSQL_RES *res = mysql_store_result(m_db);
    if (res == NULL)
    {
        std::cout << "file:" << __FILE__ << ", line:" << __LINE__ << mysql_error(m_db) << std::endl;
        return result;
    }

    // 获取列数
    unsigned int columns =  mysql_num_fields(res);
    unsigned int rows = mysql_num_rows(res);

    // 获取字段的名称（取列名）
    MYSQL_FIELD *fields = mysql_fetch_fields(res);

    // 打印所有列名的信息
    for (int idx = 0; idx < columns; idx++)
    {
        result.columnName.push_back(fields[idx].name);
    }
    std::cout << std::endl;

    // 获取每一行的数据
    MYSQL_ROW row;
    while ((row = mysql_fetch_row(res)) != NULL)
    {
        std::vector<std::string> tmpRow;
        for (int idx = 0; idx < columns; idx++)
        {
            const char *tmp = NULL;
            if (row[idx] != NULL)
            {
                tmp = row[idx];
            }
            else
            {
                tmp = "NULL";
            }
            tmpRow.push_back(tmp);
        }
        result.rows.push_back(tmpRow);
    }
    // 释放结果集
    mysql_free_result(res);

    // 返回结果集
    return result;
}

// 关闭数据库连接
void MySqlDataBase::close()
{
    mysql_close(m_db);
    m_db = nullptr;
}

// 刷新时间戳
void MySqlDataBase::refreshAliveTime()
{
    // 得到当前时间
    m_backUpCurrentTime = std::chrono::_V2::steady_clock::now();
}

// 获取数据库句柄的存活时间
long MySqlDataBase::getAliveTime()
{
    // 纳秒
    std::chrono::nanoseconds res = std::chrono::_V2::steady_clock::now() - m_backUpCurrentTime;
    // 精度转换
    std::chrono::seconds sec = std::chrono::duration_cast<std::chrono::seconds>(res);
    
    // 返回秒
    return sec.count();
}
